package Element;

import java.awt.*;
import java.awt.geom.*;

import Element.Geom.*;
import DistSys.*;

public class Arrester extends AbsElem implements Cloneable {
    public static AbsElem objActiveTemp;  //a developer's version of ActiveTemplate

    public Arrester(){ }

    public Object clone(){
        Arrester created = new Arrester();
        this.copyTo(created); // copy AbsElem attributes to created
        //created.setDftTemp(this.getDftTempName());
        //created.rel  = (ReliaInd) (this.rel.clone());
        //created.ckt  = (CktLaw) (this.ckt.clone());
        created.geom = (OneNodeElemGeom) (((OneNodeElemGeom)this.geom).clone());
        return created;
    }

    public int getType() { return SysConst.TYPE_ARRESTER; }

    public void draw(Graphics2D g2, double dist, double theta) {
        int Ax = geom.x1 + (int)(dist * Math.cos(theta)/4);
        int Ay = geom.y1 + (int)(dist * Math.sin(theta)/4);
        int Bx = geom.x1 + (int)(dist * Math.cos(theta)*3/4);
        int By = geom.y1 + (int)(dist * Math.sin(theta)*3/4);
        int Cx = (Ax + Bx)/2;
        int Cy = (Ay + By)/2;

        g2.drawLine(geom.x1,geom.y1, Ax,Ay);     //don't rotate the handle line

        int r = (int)(dist / 8.0);   // r = |N1,N2| / 8 = |A,B| / 4
        int Dx=Cx-2*r, Dy=Cy-r;
        int Ex=Cx-2*r, Ey=Cy-2*r;
        int Fx=Cx-r,   Fy=Cy-2*r;
        int Gx=Cx+r,   Gy=Cy+2*r;
        int Hx=Cx+2*r, Hy=Cy+2*r;
        int Ix=Cx+3*r, Iy=Cy-2*r;
        int Kx=Cx+3*r, Ky=Cy-r;
        int Lx=Cx+3*r, Ly=Cy;
        int Mx=Cx+3*r, My=Cy+r;
        int Nx=Cx+3*r, Ny=Cy+2*r;
        int Ox=Cx+4*r, Oy=Cy-r;
        int Px=Cx+4*r, Py=Cy;
        int Qx=Cx+4*r, Qy=Cy+r;
        int Rx=Cx+4*r, Ry=Cy+2*r;

        AffineTransform t = geom.t;
        t.setToRotation(theta, Cx, Cy);
        g2.transform(t);

        g2.drawRect(Dx,Dy, 4*r,2*r);
        g2.drawLine(Ex,Ey, Fx,Fy);
        g2.drawLine(Fx,Fy, Gx,Gy);
        g2.drawLine(Gx,Gy, Hx,Hy);
        g2.drawLine(Lx,Ly, Cx+2*r,Cy);  // L--B
        g2.drawLine(Ix,Iy, Nx,Ny);      // ----
        g2.drawLine(Ix,Iy, Ox,Oy);      // ////
        g2.drawLine(Kx,Ky, Px,Py);
        g2.drawLine(Lx,Ly, Qx,Qy);
        g2.drawLine(Mx,My, Rx,Ry);
    }

    /**
     * Returns whether the data field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the data field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getDataExists(int index) {
        // A switch is used here to be independent of the
        // AbsElem.DATA_* constant's real values.
        switch(index) {
            case AbsElem.DATA_ZONE:
            case AbsElem.DATA_LAYER:
            case AbsElem.DATA_CONST_POWER:
            case AbsElem.DATA_PF_CONST_POWER:
            case AbsElem.DATA_IS_LEADING:
            case AbsElem.DATA_RATED_POWER:
            case AbsElem.DATA_RATED_CURR:
            case AbsElem.DATA_ZONE_BUFFER0:
            case AbsElem.DATA_ZONE_BUFFER2:
            case AbsElem.DATA_ZONE_BUFFER4:
            case AbsElem.DATA_ZONE_BUFFER1:
            case AbsElem.DATA_ZONE_BUFFER3:
            case AbsElem.DATA_TEMP_FAULT:
            case AbsElem.DATA_SUST_FAULT:
            case AbsElem.DATA_OPEN_CKT:
            case AbsElem.DATA_MTTR:
            case AbsElem.DATA_VOLT_SAG_LEVEL:
            case AbsElem.DATA_RESISTANCE:
            case AbsElem.DATA_REACTANCE:
            case AbsElem.DATA_SHUNT_COND:
            case AbsElem.DATA_SHUNT_SUCEP:
            case AbsElem.DATA_CAPITAL_COST:
            case AbsElem.DATA_OM_COST:
            case AbsElem.DATA_FONT_SIZE:
            case AbsElem.DATA_IN_OPT_LIB:
            case AbsElem.DATA_MAINT_DUR:
            case AbsElem.DATA_MAINT_RATE:
            case AbsElem.DATA_OPTIMIZABLE:
            case AbsElem.DATA_PHASE:
            case AbsElem.DATA_STUDY_AREA:
            case AbsElem.DATA_UPGRADE_COST:
            case AbsElem.DATA_YEAR:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns whether the result field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the result field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getResultExists(int index) {
        // A switch is used here to be independent of the
        // AbsElem.RES_* constant's real values.
        switch(index) {
            case AbsElem.RES_QUERY_SCORE:
            case AbsElem.RES_QUERY_SCORE_PERC:
            case AbsElem.RES_MOMENT_INT:
            case AbsElem.RES_SUST_INT:
            case AbsElem.RES_OUT_DUR:
            case AbsElem.RES_VOLT_SAGS:
            case AbsElem.RES_CAPA_CONS:
            case AbsElem.RES_CAPA_CONS_KVA:
            case AbsElem.RES_KVA_FLOW:
            case AbsElem.RES_PF:
            case AbsElem.RES_VOLT_MAG:
            case AbsElem.RES_VOLT_ANG:
            case AbsElem.RES_CURR_MAG:
            case AbsElem.RES_CURR_ANG:
            case AbsElem.RES_SHORTCIRC_CURR:
            case AbsElem.RES_VOLT_DROP:
            case AbsElem.RES_CURR_LOADING:
            case AbsElem.RES_KVA_RATING:
            case AbsElem.RES_MAIFI:
            case AbsElem.RES_SAG:
            case AbsElem.RES_SAIDI:
            case AbsElem.RES_SAIFI:
            case AbsElem.RES_VOLT_MAG_NODE1:
            case AbsElem.RES_VOLT_ANG_NODE1:
            case AbsElem.RES_VOLT_SAGS_ON_TGT:

            case AbsElem.RES_VOLT_SAGS_NODE1:
            case AbsElem.RES_PROTECT_ZONE:
            case AbsElem.RES_SA_MOMENT_INT:
            case AbsElem.RES_SA_SUST_INT:
            case AbsElem.RES_SA_DUR_SI:
            case AbsElem.RES_OLV_MI:
            case AbsElem.RES_OLV_SI:
            case AbsElem.RES_OLV_DUR_SI:
            case AbsElem.RES_UVV_MI:
            case AbsElem.RES_UVV_SI:
            case AbsElem.RES_UVV_DUR_SI:
                return true;
            default:
                return false;
        }
    }
}
